package Models;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import utils.GetConnection;

import com.mysql.jdbc.Statement;

public class Purchase {
	
	private long id;
	private Customer customer;
	private String date;
	private ArrayList<OrderLine> list_products;
	private float total_price = 0;
	
	public Purchase(){}
	public Purchase(long id){
		PreparedStatement stm = null;
		PreparedStatement stm2 = null;
		try {
			String req = "select * from purchases where id = ?;";
			String req2 = "select id from order_lines where purchase_id = ?;";
			stm = GetConnection.getConnection().prepareStatement(req);
			stm2 = GetConnection.getConnection().prepareStatement(req2);
			
			stm.setLong(1, id);
			stm2.setLong(1, id);
			ResultSet res = stm.executeQuery();
			if(res.next()){
				this.id = res.getLong("id");
				this.date = res.getString("date");
				this.total_price = res.getFloat("total_price");
				this.customer = Customer.LoadSql(res.getInt("customer_id"));
				this.list_products = new ArrayList<OrderLine>();
				
				res = stm2.executeQuery();	
				while(res.next()){
					this.list_products.add(new OrderLine(res.getLong("id")));
				}
			}
		}
		catch (SQLException e) {e.printStackTrace();}
		finally{
			try {
				if(stm != null) stm.close();
				if(stm2 != null) stm2.close();
			} catch (SQLException e) {}
		}

	}
	
	public long getId() {return id;}
	public void setId(long id) {this.id = id;}
	public float getTotal_price() {return total_price;}
	public void setTotal_price(float price) {this.total_price = price;}
	public Customer getCustomer() {return customer;}
	public void setCustomer(Customer customer) {this.customer = customer;}
	public String getDate() {return date;}
	public void setDate(String date) {this.date = date;}
	public ArrayList<OrderLine> getList_products() {return list_products;}
	public void setList_products(ArrayList<OrderLine> list_products) {this.list_products = list_products;}
	
	public void addOrderLine(OrderLine line){
		if(list_products == null) list_products = new ArrayList<OrderLine>();	
		list_products.add(line);
	}
	
	public boolean create() throws PurchaseException{
		if(! itemAreAllinStock()){
			throw new PurchaseException("Commande invalide, Pas assez de stock.");
		}

		String req = "insert into purchases(customer_id,total_price,date) values(?,?,?)";
		try {
			PreparedStatement stm = GetConnection.preparedTransacStatement(req,Statement.RETURN_GENERATED_KEYS);
			
			stm.setInt(1, customer.getId());
			stm.setInt(2, 0);
			stm.setString(3, date);
			if(stm.executeUpdate() == 0)
				throw new SQLException("Echec insert");
			
			ResultSet res = stm.getGeneratedKeys();
			res.next();
			id = res.getLong(1) ;
			if(createAllOrderLines()){
				GetConnection.commit();
				updateStockQuantity();
				return true;
			}
		} catch (SQLException e) {e.printStackTrace();}
		
		GetConnection.rollback();
		return false;
	}
	
	private void updateStockQuantity() {
		for(OrderLine o : list_products)
			o.removeItemFromStock();
	}
	
	private boolean itemAreAllinStock() {
		for(OrderLine o : list_products)
			if(! o.getProduct().hasEnough(o.getQte()))
				return false;
		
		return true;
	}
	private void updateTotalPrice(float price){
		String req = "update purchases set total_price = ? where id = ? ;";
		try {
			PreparedStatement con = GetConnection.preparedTransacStatement(req);
			
			con.setFloat(1, price);
			con.setLong(2, id);
			con.execute();
			
		} catch (SQLException e) {e.printStackTrace();}
	}

	
	private boolean createAllOrderLines(){
		float total_price = 0;
		for(OrderLine line : list_products){
			if(! line.create(id))
				return false;
			total_price += (line.getProduct().getPrice() * line.getQte());
		}	
		
		updateTotalPrice(total_price);
		return true;
	}
	
	public static ArrayList<Purchase> getAll(){
		ArrayList<Purchase> list = new ArrayList<Purchase>();
		
		PreparedStatement stm = null;
		try {
			String req = "select id from purchases;";
			stm = GetConnection.getConnection().prepareStatement(req);				
			ResultSet res = stm.executeQuery();
			while(res.next()){
				Purchase p = new Purchase(res.getLong("id"));
				list.add(p);
			}
		}
		catch (SQLException e) {e.printStackTrace();}
		finally{
			try {
				if(stm != null) stm.close();
			} catch (SQLException e) {}
		}

		return list;		
	}
	
	public class PurchaseException extends Exception{
		PurchaseException(String msg){super(msg);}
		PurchaseException(){}
	}
}
